﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Net;
using System.Net.Sockets;

namespace Assignment2
{

    class Retailer
    {
        private Int32 currentNumberOfChickens = 0;
        private Int32 minimumNumberOfChickens = 5;
        private Int32 idealNumberOfChickens = 20;
        private Int32 idealPrice = 1200;
        private Order currentOrder;
        private Boolean doNotOrder = false;
        private Int64 creditCardNumber = 1234567890123456;
        private int id;
        private bool _keepAlive;

        public Retailer(int i)
        {
            id = i;

            _keepAlive = true;

            // register to teh server shutdown event
            ChickenFarm.retailer_shutdown_event += new RetailerShutdownEvent(shutdown_retailer);

            // register with the orderprocesser to receive completed orders
            OrderProcessingThread.order_complete += new OrderProcessingEvent(complete_order);

            // register with the ChickenFarm event callback scheme
            ChickenFarm.price_cut_event += new PriceCutEvent(this.chickenOnSale);
        }

        public Retailer() { }


        public void RetailerFunc() //start thread with this
        {
            Random random = new Random();

            int delay = 3 * random.Next(0, 1000);
            Thread.Sleep(delay);
            Console.WriteLine("Retailer " + this.id + " says hi");     

            // JSC: need to keep alive your thread here
            //      set _keepAlive to false when you receive the kill command
            while (_keepAlive == true)
            {
                Thread.Sleep(1000);
            }

            // retailer thread is about to terminate
            Logger.log_message("Retailer thread " + this.id + " is terminating.");

        }

        /*
         * These are the retailer-specific functions.
         */

        // Kill this retailer
        private void complete_order(Order order)
        {
            try
            {
                if (currentOrder != null)
                {
                    // make sure the order is the right one
                    if (order.getSenderId() == currentOrder.getSenderId())
                    {
                        currentNumberOfChickens += currentOrder.getNumberOfChickens();
                    }
                }
                doNotOrder = false;
            }
            catch (Exception ex)
            {
                String message =
                    "Exception caught in Retailer handle_transaction: " +
                    ex.ToString();

                Logger.log_message(message);
            }
        }

        // Kill this retailer
        private void shutdown_retailer()
        {
            //kill me!
            _keepAlive = false;

            // User feedback
            Logger.log_message("Retailer " + this.id + " received kill packet.");
            Console.WriteLine("Retailer " + this.id + " received kill packet.");
        }

        //the event handler if there is a price reduction at the wholesale level
        public void chickenOnSale(Int32 p) // p = new price
        {
            Encoder encodedOrder;

            if (!doNotOrder)
            {
                if (currentNumberOfChickens < idealNumberOfChickens && p < idealPrice) //if there's room for the chickens and the price is right
                {   //stock up
                    currentOrder = createOrder(idealNumberOfChickens - currentNumberOfChickens);
                    currentOrder.placeOrder();
                    encodedOrder = new Encoder(currentOrder);

                    //send to MultiCellBuffer
                    MultiCellBuffer.setOneCell(encodedOrder.encode());
                    doNotOrder = true;
                }
                else if (currentNumberOfChickens < minimumNumberOfChickens) //if we're dangerously low on chickens
                {   //order just enough to get by
                    currentOrder = createOrder(minimumNumberOfChickens - currentNumberOfChickens + 1);
                    currentOrder.placeOrder();
                    encodedOrder = new Encoder(currentOrder);

                    //send to MultiCellBuffer
                    MultiCellBuffer.setOneCell(encodedOrder.encode());
                    doNotOrder = true;
                }
                else
                {
                    sellChicken();
                } // rough mechanism to get rid of chickens to create need; in real system, this would be Customer class
            }

            //Console.WriteLine("Retailer " + this.id + " has " + currentNumberOfChickens.ToString() + " chickens");
        }

        //bundle up the order
        private Order createOrder(Int32 num)
        {
            Order theOrder;

            theOrder = new Order(id);
            theOrder.setCardNumber(creditCardNumber);
            theOrder.setNumberOfChickens(num);

            return (theOrder);
        }

        //goodbye, chicken
        private void sellChicken()
        {
            if (currentNumberOfChickens > 4)
            {
                currentNumberOfChickens = currentNumberOfChickens - 5; ;
            }
        }

    }
}
